'''
Created on Jan 11, 2013

@author: mmoran
'''
import os
import webapp2
import jinja2
import json
import logging
from webapp2_extras import auth
from webapp2_extras import sessions
from webapp2_extras.auth import InvalidAuthIdError
from webapp2_extras.auth import InvalidPasswordError
from google.appengine.ext import db
from gcmmod import GCM

from tweepy.streaming import StreamListener, Stream
from tweepy.auth import OAuthHandler
from tweepy.api import API
import tweepy

from models import *
import settings



class BaseHandler(webapp2.RequestHandler):
    
    def get_user(self, username):
        q = AUser.all()
        q.filter("username =", 'mmoran')
        user = q.get()
        return user


class ObservableHandler(BaseHandler):
    def get_observable_dict(self, obs):
        return dict(owner=dict(first_name=obs.owner.first_name,last_name=obs.owner.last_name,email=obs.owner.email,username=obs.owner.username),
                    uid=obs.uid,name=obs.name,profile_image_url=obs.profile_image_url,o_id=str(obs.key()),screen_name=obs.screen_name)

    def get(self, username=None, o_id=None):
        user = self.get_user(username)
        response = {'data':[]}
        if username:
            if o_id:
                o = db.get(o_id)
                if o:
                    response['data'] = self.get_observable_dict(o)
            else:
                q = Observable.all().filter('owner =', user)
                response = {'data':[]}
                logging.info(q)
                for o in q:
                    response['data'].append(self.get_observable_dict(o))
        else:
            q = Observable.all()
            for o in q:
                response['data'].append(self.get_observable_dict(o))
        self.response.headers['Content-Type'] = 'application/json'   
        self.response.out.write(json.dumps(response))

    def post(self, username):
        screen_name = self.request.POST.get('username')
        user = self.get_user(username)
        api = API(settings.auth)
        r = api.get_user(screen_name)
        # data = dict(id_str=r.id_str,name=r.name,
        #             profile_image_url=r.profile_image_url,screen_name=r.screen_name)
        o = Observable(owner=user, uid=r.id_str, name=r.name, screen_name=r.screen_name,
                       profile_image_url=r.profile_image_url)
        o.put()
        logging.info(o.key())
        self.response.headers['Content-Type'] = 'application/json'   
        self.response.out.write(json.dumps({'data':self.get_observable_dict(o)}))

    def delete(self, username, o_id):
        db.delete(o_id)
        self.response.headers['Content-Type'] = 'application/json'   
        self.response.out.write(json.dumps({'data':{'status':'ok'}}))


class ReportsHandler(BaseHandler):
    
    def report_to_dict(self, report):
        return dict(victim=dict(owner=dict(first_name=report.victim.owner.first_name,last_name=report.victim.owner.last_name,email=report.victim.owner.email,username=report.victim.owner.username),
                    uid=report.victim.uid,name=report.victim.name,profile_image_url=report.victim.profile_image_url,o_id=str(report.victim.key()),screen_name=report.victim.screen_name),text=report.text,
                    created_at=str(report.created_at.date()), ranking=report.rank, r_id=str(report.key()), aggressor=dict(a_id=str(report.aggressor.key()),screen_name=report.aggressor.screen_name,profile_image_url=report.aggressor.profile_image_url,
                    ranking=report.aggressor.ranking))
    
    def get(self,username=None, o_id=None):
        o = db.get(o_id)
        q = Report.all().filter('victim =',o)
        reports = {'data':[]}
        for r in q:
            reports['data'].append(self.report_to_dict(r))
        self.response.headers['Content-Type'] = 'application/json'   
        self.response.out.write(json.dumps(reports))

    def post(self):
        o_id = self.request.POST.get('o_id')
        o = db.get(o_id)
        a_id = self.request.POST.get('a_id')
        a = db.get(a_id)
        text = self.request.POST.get('text')
        rank = self.request.POST.get('rank')
        r = Report(victim=o,aggressor=a,text=text,rank=int(rank))
        r.put()
        logging.info(r.key())
        self.response.headers['Content-Type'] = 'application/json'   
        self.response.out.write(json.dumps({"data":self.report_to_dict(r)}))

    def put(self, r_id):
        r = db.get(r_id)
        rank = self.request.POST.get('rank')
        r.rank = int(rank)
        r.checked = True
        r.aggressor.reports.append(r.key())
        r.aggressor.ranking = (r.aggressor.ranking + r.rank * 2) / 2
        r.put()
        self.response.headers['Content-Type'] = 'application/json'   
        self.response.out.write(json.dumps({'data':self.report_to_dict(r)}))

class AggressorHandler(BaseHandler):

    def aggresor_to_dict(self, a):
        return dict(a_id=str(a.key()),screen_name=a.screen_name,profile_image_url=a.profile_image_url,
                    ranking=a.ranking)

    def get(self, screen_name):
        a = Aggressor.all().filter('screen_name =', screen_name).get()
        response = {'error':'no existe'}
        if a:
            response={'data':dict(a_id=str(a.key()),screen_name=a.screen_name,profile_image_url=a.profile_image_url, ranking=a.ranking)}
        self.response.headers['Content-Type'] = 'application/json'   
        self.response.out.write(json.dumps(response))

    def post(self):
        screen_name = self.request.POST.get('screen_name')
        api = API(settings.auth)
        r = api.get_user(screen_name)
        #data = dict(id_str=r.id_str, name=r.name, profile_image_url=r.profile_image_url, screen_name=r.screen_name)
        logging.info(r.id_str)
        a = Aggressor(uid=r.id_str, name=r.name, screen_name=r.screen_name, profile_image_url=r.profile_image_url)
        a.put()
        logging.info(a.key())
        self.response.headers['Content-Type'] = 'application/json'   
        self.response.out.write(json.dumps({'data':self.aggresor_to_dict(a)}))


class NotifyHandler(BaseHandler):
    def post(self):
        gcm = GCM('AIzaSyD4S2STRZjjAlzg3CyJUOXyUUrbkt3xyBc')
        reg_ids = ['APA91bGKPsmKgYtVdkzglru5FlxvNFGF6joDtvFoXdTf00sA-CRwBv4fLeOfuM22IUTpYWwYRp_jddiUSmG9qn44S1DYTryViwuUE4b0dB1rJwbx3jsHlcBt6VuXckZZcjwt03HAoSszuebaA07Yf_oMzvXzQ3PlAzin629OcWewb53EcW7dDlE'] #viejo
        #reg_ids = ['APA91bGbW6wHDlO7yssDO3YuHSUv5WGM_D7Un--Yixfom2ptyOfZCF5lUf_XADA4pksO8SjokIx9jmkdFHrU5zr3W50_fVHK6KkQvqK3N7yBtH6DpBTsBi3GHf6kJ6w0L8-atyI0_ee8zI5dxQLgDpfgNvHo-5FbGw']

        # reg_ids = [str(self.request.get('registration_id'))]
        # data = {'text':'%s||%s||%s'}
        logging.info(self.request.body)
        data = {'text':str(self.request.get('text')),
                'code':str(self.request.get('code')),
                'level':str(self.request.get('level')),
                'victims':str(self.request.get('victims')),
                'scrapper':str(self.request.get('scrapper'))}
        logging.info(data)
        res = gcm.json_request(registration_ids=reg_ids, 
                               data=data,collapse_key='antibullying_notifier',
                               delay_while_idle=False, time_to_live=3600) 
        self.response.headers['Content-Type'] = 'application/json'    
        self.response.out.write(json.dumps(dict(results={'status':res}))) 


logging.getLogger().setLevel(logging.DEBUG)
app = webapp2.WSGIApplication([
    webapp2.Route(r'/api/observables/', handler=ObservableHandler),
    webapp2.Route(r'/api/<username>/observables/', handler=ObservableHandler),
    webapp2.Route(r'/api/<username>/observables/<o_id>/', handler=ObservableHandler),
    webapp2.Route(r'/api/<username>/observables/<o_id>/reports/', handler=ReportsHandler),
    webapp2.Route(r'/api/reports/', handler=ReportsHandler),
    webapp2.Route(r'/api/reports/<r_id>/', handler=ReportsHandler),
    webapp2.Route(r'/api/aggressor/', handler=AggressorHandler),
    webapp2.Route(r'/api/aggressor/<screen_name>/', handler=AggressorHandler),
    webapp2.Route(r'/api/notify/', handler=NotifyHandler)], debug=True)